/****************************************************************************
**
** Copyright (C) 2009-2010 Mist Poryvaev.
** All rights reserved.
** Contact: Mist Poryvaev (mist.poryvaev@gmail.com)
**
** This file is part of the RailWorm project.
**
****************************************************************************/

#include "ordertickets.h"
#include "ui_ordertickets.h"
#include "connectrzd.h"
#include "railwormsplash.h"

OrderTickets * OrderTickets::g_Instance = 0;
QSettings OrderTicketsSettings("railworm.ini", QSettings::IniFormat);

OrderTickets * OrderTickets::i() {
	if (g_Instance == 0) {
		g_Instance = new OrderTickets();
	}
	return g_Instance;
}

OrderTickets::OrderTickets(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OrderTickets) {
    ui->setupUi(this);
    m_SetupLogon = SetupLogon::i();

	ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Продолжить"));
	ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Отмена"));
	ui->DetailsTable->setColumnWidth(0, 250);
	ui->PersonalDataTable->setColumnWidth(0, 250);

	ui->PersonalDataTable->setCellWidget(PD_TYPE, 0, m_DocType = new QComboBox());
	m_DocType->addItem(tr("ПН: Паспорт РФ"), tr("ПН"));
	m_DocType->addItem(tr("ПС: Паспорт формы СССР"), tr("ПС"));
	m_DocType->addItem(tr("ЗП: Заграничный паспорт"), tr("ЗП"));
	m_DocType->addItem(tr("ЗЗ: Иностранный документ"), tr("ЗЗ"));
	m_DocType->addItem(tr("ПМ: Паспорт моряка"), tr("ПМ"));
	m_DocType->addItem(tr("СР: Свидетельство о рождении"), tr("СР"));
	m_DocType->addItem(tr("ВБ: Военный билет"), tr("ВБ"));

	ui->SavePersonalData->setChecked(OrderTicketsSettings.value("OrderTickets/SavePersonalData", false).toBool());
	if (ui->SavePersonalData->isChecked()) {
		ui->PersonalDataTable->setItem(PD_SURNAME, 0, new QTableWidgetItem(OrderTicketsSettings.value("OrderTickets/Surname", "").toString()));
		ui->PersonalDataTable->setItem(PD_NAME, 0, new QTableWidgetItem(OrderTicketsSettings.value("OrderTickets/Name", "").toString()));
		ui->PersonalDataTable->setItem(PD_MIDNAME, 0, new QTableWidgetItem(OrderTicketsSettings.value("OrderTickets/Midname", "").toString()));
		m_DocType->setCurrentIndex(OrderTicketsSettings.value("OrderTickets/DocType", "0").toInt());
		ui->PersonalDataTable->setItem(PD_SERIAL, 0, new QTableWidgetItem(OrderTicketsSettings.value("OrderTickets/Serial", "").toString()));
	}
	else {
		ui->PersonalDataTable->setItem(PD_SURNAME, 0, new QTableWidgetItem(""));
		ui->PersonalDataTable->setItem(PD_NAME, 0, new QTableWidgetItem(""));
		ui->PersonalDataTable->setItem(PD_MIDNAME, 0, new QTableWidgetItem(""));
		ui->PersonalDataTable->setItem(PD_SERIAL, 0, new QTableWidgetItem(""));
	}

	m_LastAccessTime = QDateTime::currentDateTime().addDays(-1);
	m_Login = "";
	m_Password = "";

	bank = new QWebView();
	bank->page()->setNetworkAccessManager(& jinn.NetMan());
	connect(bank,SIGNAL(loadFinished(bool)), this, SLOT(OnGateFinished(bool)));
	login = new QWebView();
	login->page()->setNetworkAccessManager(& jinn.NetMan());
	connect(login, SIGNAL(loadFinished(bool)), this, SLOT(OnAccountFinished(bool)));
}

OrderTickets::~OrderTickets() {
    delete ui;
}

void OrderTickets::QuitAccount(HtmlResponse * _response, bool _error) {
	m_LastAccessTime = QDateTime::currentDateTime().addDays(-1);
	RailWormSplash::i()->hide();
	if (_error) {
		QMessageBox::information(0, tr("Ошибка формата страницы"), tr("Ответ от узла ticket.rzd.ru не распознан"));
	}
	if (_response) {
		if (_error) {
/*
			QPlainTextEdit * te = new QPlainTextEdit();
			te->setPlainText(_response->Data());
			te->show();
*/
		}

		delete _response;
	}
}

void OrderTickets::on_PrevPage_clicked() {
	ui->PrevPage->setEnabled(true);
	ui->NextPage->setEnabled(true);
	if (ui->tabWidget->currentIndex() > 0) {
		ui->tabWidget->setCurrentIndex(ui->tabWidget->currentIndex() - 1);
	}
}

void OrderTickets::on_NextPage_clicked() {
	ui->PrevPage->setEnabled(true);
	ui->NextPage->setEnabled(true);
	if (ui->tabWidget->currentIndex() < ui->tabWidget->count() - 1) {
		ui->tabWidget->setCurrentIndex(ui->tabWidget->currentIndex() + 1);
	}
}

void OrderTickets::on_tabWidget_currentChanged(int index) {
	ui->PrevPage->setEnabled(index != 0);
	ui->NextPage->setEnabled(index != ui->tabWidget->count() - 1);
	ui->buttonBox->setEnabled(index == ui->tabWidget->count() - 1);
}

void OrderTickets::Execute(TrainDataStruct tds) {
	qDebug() << __FUNCTION__;
	if (m_SetupLogon->IsValid() == false) {
		m_SetupLogon->exec();
	}
	if (m_SetupLogon->IsValid()) {	

		// заполняем реквизиты поездки
		ui->DetailsTable->setItem(0, 0, new QTableWidgetItem(tds.Name));
		ui->DetailsTable->setItem(1, 0, new QTableWidgetItem(tds.Path));
		ui->DetailsTable->setItem(2, 0, new QTableWidgetItem(tds.Start));
		ui->DetailsTable->setItem(3, 0, new QTableWidgetItem(tds.End));
		ui->DetailsTable->setItem(4, 0, new QTableWidgetItem(tds.Class.at(0).Class));
		ui->DetailsTable->setItem(5, 0, new QTableWidgetItem(tds.Class.at(0).Car.at(0).Number));
		ui->DetailsTable->setItem(6, 0, new QTableWidgetItem(tds.Class.at(0).Price));
		// ------

		// проверяем время последнего обращения. если был успешный логин и прошло менее 10 минут, то логиниться снова не надо
		if (m_LastAccessTime.secsTo(QDateTime::currentDateTime()) < 600) {
			if ((m_Login == m_SetupLogon->Login()) && (m_Password == m_SetupLogon->Password())) {
				OnLoggedPageFinished(new HtmlResponse(m_LoggedInResponse), 0x7fffffff, false);
				return;
			}
		}
		// ----

		m_Login = m_SetupLogon->Login();
		m_Password = m_SetupLogon->Password();

		RailWormSplash::i()->show();
		RailWormSplash::i()->showMessage(tr("Вход на ticket.rzd.ru..."), Qt::AlignCenter);
		m_tds = tds;

		m_VehicleCode = m_tds.Class.at(0).Car.at(0).VehicleCode;

		jinn.Request(QString(rzd::Query("Ticket") + "pp"), HtmlGenie::ContentTypeText(), this, SLOT(OnStartPageFinished(HtmlResponse*,int,bool)));
	}
}

void OrderTickets::OnStartPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	HtmlElementPars _pars;
	_pars.Class = "wpsToolBarLink";
	_pars.Content = tr("Вход");
	HtmlLinkDataList _links_list = Response->Links(_pars);
	if (_links_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(_links_list.at(0).Url, HtmlGenie::ContentTypeText(), this, SLOT(OnLoginPageFinished(HtmlResponse*,int,bool)));
}

void OrderTickets::OnLoginPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Авторизация пользователя ") + m_SetupLogon->Login() + "...", Qt::AlignCenter);

	HtmlElementPars _pars;
	_pars.Name = "LoginForm";
	HtmlFormDataList _forms_list = Response->Forms(_pars);
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	m_LoginUrl = _forms_list.at(0).Action +
					   "?wps.portlets.userid=" + m_Login +
					   "&password=" + m_Password;


	delete Response;
	jinn.Request(m_LoginUrl, HtmlGenie::ContentTypeText(), this, SLOT(OnLoggedPageFinished(HtmlResponse*,int,bool)));

}

void OrderTickets::OnLoggedPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	RailWormSplash::i()->hide();
	if (CheckLoggedIn(Response->Data())) {
		qDebug() << "ticket.rzd.ru - we're logged in";
		m_LoggedInResponse = Response->Data();
		ui->tabWidget->setCurrentIndex(0);
		int result = exec();
		OrderTicketsSettings.setValue("OrderTickets/SavePersonalData", ui->SavePersonalData->isChecked());
		if (ui->SavePersonalData->isChecked()) {
			OrderTicketsSettings.setValue("OrderTickets/Surname", ui->PersonalDataTable->item(PD_SURNAME, 0)->text());
			OrderTicketsSettings.setValue("OrderTickets/Name", ui->PersonalDataTable->item(PD_NAME, 0)->text());
			OrderTicketsSettings.setValue("OrderTickets/Midname", ui->PersonalDataTable->item(PD_MIDNAME, 0)->text());
			OrderTicketsSettings.setValue("OrderTickets/DocType", m_DocType->currentIndex());
			OrderTicketsSettings.setValue("OrderTickets/Serial", ui->PersonalDataTable->item(PD_SERIAL, 0)->text());
		}
		else {
			OrderTicketsSettings.setValue("OrderTickets/Surname", "");
			OrderTicketsSettings.setValue("OrderTickets/Name", "");
			OrderTicketsSettings.setValue("OrderTickets/Midname", "");
			OrderTicketsSettings.setValue("OrderTickets/DocType", 0);
			OrderTicketsSettings.setValue("OrderTickets/Serial", "");
		}

		if (result == QDialog::Rejected) {
			delete Response;
			return;
		}
	}
	else {
		QMessageBox::information(0, tr("Не удалось залогиниться"), tr("Проверьте корректность логина и пароля"));
		delete Response;
		return;
	}

	m_LastAccessTime = QDateTime::currentDateTime();

	RailWormSplash::i()->show();
	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Пожалуйста, подождите..."), Qt::AlignCenter);

	HtmlElementPars _pars;
	_pars.Content = tr("Покупка билета");
	HtmlLinkDataList _links_list = Response->Links(_pars);
	if (_links_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;

	m_BuyUrl = _links_list.at(0).Url.toString();
	jinn.Request(m_BuyUrl, HtmlGenie::ContentTypeText(), this, SLOT(OnBuyPageFinished(HtmlResponse*,int,bool)));

}

void OrderTickets::OnBuyPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	if (Response->Data().contains(tr("Ожидание подтверждения оплаты заказа с платежного шлюза"), Qt::CaseInsensitive)) {
		QuitAccount(Response, false);
		QMessageBox::information(0, tr("Пожалуйста, подождите"), tr("Предыдущая транзакция будет завершена в течение десяти минут"));
		return;
	}

	HtmlElementPars _pars;
	_pars.Id = "submitBtnId";
	HtmlInputDataList _inputs_list = Response->Inputs(_pars);
	if (_inputs_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	QString _on_click = _inputs_list.at(0).Attributes.value("onclick").toString();
	QString _url;
	foreach (const QString & _on_click_par, _on_click.split(";")) {
		if (_on_click_par.contains("location")) {
			_url = _on_click_par.split("=").at(1);
			_url = _url.replace("'", "").simplified();
			break;
		}
	}
	if (_url.isEmpty()) {
		QuitAccount(Response, true);
		return;
	}

	qDebug() << "confirm - " << _url;

	delete Response;
	jinn.Request("http://" + rzd::TicketHost() + _url, HtmlGenie::ContentTypeText(), this, SLOT(OnFromToPageFinished(HtmlResponse*,int,bool)));
}

void OrderTickets::OnFromToPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Запись маршрута..."), Qt::AlignCenter);

	HtmlFormDataList _forms_list = Response->Forms();
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(
			_forms_list.at(0).Action +
			"?PC_7_005UK188OF0KJKOJ6I10000000_sl_src=" + m_tds.From +
			"&PC_7_005UK188OF0KJKOJ6I10000000_sl_dst=" + m_tds.To +
			"&PC_7_005UK188OF0KJKOJ6I10000000_sl_nrtickets=1" +
			"&PC_7_005UK188OF0KJKOJ6I10000000_sl_date=" + m_tds.Start.simplified().split(" ").at(0),
			HtmlGenie::ContentTypeText(),
			this,
			SLOT(OnSelectTrainPageFinished(HtmlResponse*,int,bool))
			);
}

void OrderTickets::OnSelectTrainPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;

	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Запись номера поезда..."), Qt::AlignCenter);

	HtmlFormDataList _forms_list = Response->Forms();
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(
			_forms_list.at(0).Action +
			"?sl_train=" + m_tds.OriginalName,
			HtmlGenie::ContentTypeText(),
			this,
			SLOT(OnSelectVehiclePageFinished(HtmlResponse*,int,bool))
			);
}

void OrderTickets::OnSelectVehiclePageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Запись класса вагона..."), Qt::AlignCenter);

	HtmlFormDataList _forms_list = Response->Forms();
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(
			"https://" + rzd::TicketHost() + _forms_list.at(0).Action +
			"?sl_vnumber=" + m_VehicleCode,
			HtmlGenie::ContentTypeText(),
			this,
			SLOT(OnPersonalDataPageFinished(HtmlResponse*,int,bool))
			);

}

void OrderTickets::OnPersonalDataPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;

	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Ввод персональных данных..."), Qt::AlignCenter);

	HtmlFormDataList _forms_list = Response->Forms();
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(
			_forms_list.at(0).Action +
			// фамилия
			"?PC_7_005UK188OF0KJKOJ6I10000000_sel_Lname_0=" + ui->PersonalDataTable->item(PD_SURNAME, 0)->text() +
			// имя
			"&PC_7_005UK188OF0KJKOJ6I10000000_sel_Fname_0=" + ui->PersonalDataTable->item(PD_NAME, 0)->text() +
			// отчество
			"&PC_7_005UK188OF0KJKOJ6I10000000_sel_Mname_0=" + ui->PersonalDataTable->item(PD_MIDNAME, 0)->text() +
			// тип документа
			"&PC_7_005UK188OF0KJKOJ6I10000000_sel_passport_type_0=" + m_DocType->itemData(m_DocType->currentIndex(), Qt::UserRole).toString() +
			// номер документа
			"&PC_7_005UK188OF0KJKOJ6I10000000_sel_passport_number_0=" + ui->PersonalDataTable->item(PD_SERIAL, 0)->text().replace(" ", "") +
			// взрослый
			"&PC_7_005UK188OF0KJKOJ6I10000000_sel_is_chld_0=N" +
			// постельные принадлежности (только в плацкарте)
			(QString(m_VehicleCode).remove(0, 6).contains("3") ? QString("&PC_7_005UK188OF0KJKOJ6I10000000_sl_bed_clothes=Y") : QString("")),
			HtmlGenie::ContentTypeText(),
			this,
			SLOT(OnCheckParamsPageFinished(HtmlResponse*,int,bool))
			);
}

void OrderTickets::OnCheckParamsPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Потверждение реквизитов поездки..."), Qt::AlignCenter);

	HtmlFormDataList _forms_list = Response->Forms();
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(
			_forms_list.at(0).Action,
			HtmlGenie::ContentTypeText(),
			this,
			SLOT(OnCheckOrderPageFinished(HtmlResponse*,int,bool))
			);

}

void OrderTickets::OnCheckOrderPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Оформление покупки билета. Переход к оплате заказа..."), Qt::AlignCenter);

	HtmlFormDataList _forms_list = Response->Forms();
	if (_forms_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	delete Response;
	jinn.Request(
			_forms_list.at(0).Action,
			HtmlGenie::ContentTypeText(),
			this,
			SLOT(OnPayPageFinished(HtmlResponse*,int,bool))
			);

}

void OrderTickets::OnPayPageFinished(HtmlResponse * Response, int Id, bool _Error) {
	qDebug() << __FUNCTION__;
	if (_Error) {
		QuitAccount(Response, true);
		return;
	}

	RailWormSplash::i()->showMessage(tr("Завершение сеанса, переход на страницу состояния покупки..."), Qt::AlignCenter);

	/*
	QPlainTextEdit * te = new QPlainTextEdit();
	te->setWindowTitle(__FUNCTION__);
	te->setPlainText(Response->Data());
	te->show();
*/
	HtmlElementPars _pars;
	_pars.Content = "transcredit.ru";
	HtmlScriptDataList _list = Response->Scripts();

	if (_list.size() == 0) {
		QuitAccount(Response, true);
		return;
	}

	QString _url;
	foreach (const QString & _par, _list.at(0).Code.split(";")) {
		if (_par.contains("location")) {
			_url = _par.right(_par.length() - _par.indexOf("=") - 1);
			_url = _url.replace("'", "").simplified();
			break;
		}
	}
	m_BankUrl = _url;


	delete Response;

	bank->load(QUrl(m_BankUrl));
	qDebug() << "_bank->load" << m_BankUrl;
	login->load(QUrl(m_BuyUrl));
	qDebug() << "_login->load" << m_BuyUrl;

	int _bank_idx = ui->tabWidget->addTab(bank, tr("Оплата по карте"));
	int _login_idx = ui->tabWidget->addTab(login, tr("Аккаунт РЖД"));
	ui->tabWidget->setCurrentIndex(_bank_idx);

	RailWormSplash::i()->hide();

	int _result = exec();

	ui->tabWidget->removeTab(_bank_idx);
	ui->tabWidget->removeTab(_login_idx);
}

bool OrderTickets::CheckLoggedIn(const QString & _data) {
	HtmlElementPars _pars;
	_pars.Class = "wpsToolBarLink";
	_pars.Content = tr("Выход");
	HtmlLinkDataList _links_list = HtmlResponse::Links(_data, _pars);
	if (_links_list.size() > 0) {
		return true;
	}
	return false;
}

void OrderTickets::OnGateFinished(bool _ok) {
	QWebElement _doc = bank->page()->mainFrame()->documentElement();

	foreach(QWebElement _el, _doc.findAll("img")) { _el.removeFromDocument(); }
	_doc.findFirst("#wrapper").setAttribute("style", "width:300px;");
	_doc.findFirst("#title").setAttribute("style", "width:300px;font-size:40%;");
	_doc.findFirst("#sections").setAttribute("style", "width:300px;");
	_doc.findFirst("#main").setAttribute("style", "width:300px;");
}

void OrderTickets::OnAccountFinished(bool _ok) {
	QWebElement _doc = login->page()->mainFrame()->documentElement();

	foreach(QWebElement _el, _doc.findAll(".left")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".date_bar")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".date_bar2")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".date_bar3")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".date_bar4")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".date_bar5")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".collage")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".collage_border")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".m1")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".m2")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".m3")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".banner")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll(".collage")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll("#bottom")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll("#header")) { _el.removeFromDocument(); }
	foreach(QWebElement _el, _doc.findAll("#stagenavigator")) { _el.removeFromDocument(); }

	_doc.findAll(".wpsPortletBody").last().removeFromDocument();

	_doc.findFirst("#formbox").setAttribute("style", "width:300px;");
	foreach(QWebElement _el, _doc.findAll("td.sch_fldname")) { _el.removeAttribute("nowrap"); }
	foreach(QWebElement _el, _doc.findAll("td.sch_fldcontent")) { _el.removeAttribute("nowrap"); }
}
